<?php

namespace app\tools;

use Yii;
use app\models\Merchant;
use app\tools\Curl;
use app\tools\Tool;

class WxPay {
  //微信支付/退款/零钱打款等相关操作方法

  //微信支付
  public static function pay($mch_id, $order, $openid, $mch_key, $body_name, $trade_type, $notify_url) {
    $param["appid"] = Yii::$app->params['wechatConfig']['app_id'];
		$param["mch_id"] = $mch_id;
		$param["nonce_str"] = md5(time().rand().$order->order_sn);
		$param["body"] = $body_name;
		$param["out_trade_no"] = $order->order_sn;
		$param["total_fee"] = $order->money * 100; //金额单位:分
		$param["spbill_create_ip"] = self::getIp();
		$param["notify_url"] = $notify_url;
    $param["trade_type"] = $trade_type;
    if ($openid) {
      $param["openid"] = $openid;
    }
		$sign = self::getSign($param, $mch_key);
		$param["sign"] = $sign;
    $xml = self::ToXml($param);
		$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		$response = Curl::curl_post($url, $xml);
		$res = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)));
		return $res;
  }

  //微信退款
  public static function refund($order, $money) {
    $param["appid"] = Yii::$app->params['wechatConfig']['app_id'];
		$param["mch_id"] = $order->mch_id ? $order->mch_id : Yii::$app->params['wx_pay']['mch_id'];
		$param["nonce_str"] = md5(time().rand().$order->order_sn);
		$param["out_trade_no"] = $order->order_sn;
		$param["out_refund_no"] = time().rand(0,9999);
		$param["total_fee"] = $order->money * 100; //金额单位:分
		$param["refund_fee"] = $money * 100; //金额单位:分
    $key = $order->mch_key ? $order->mch_key : Yii::$app->params['wx_pay']['key'];
		$sign = self::getSign($param, $key);
		$param["sign"] = $sign;
		$xml = self::ToXml($param);
		$url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
		$response = Curl::curl_wx_pay($url, $xml, $param["mch_id"]);
		$res = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)));
		return $res;
  }

  //微信零钱付款
  public static function payToWallet($live_name, $openid, $amount) {
    $order_sn = time().rand(1000,9999);
    $merchant = Merchant::find()->where(['type' => 2])->one();
    $mch_id = $merchant ? $merchant->mch_id : Yii::$app->params['wx_pay']['mch_id'];
    $mch_key = $merchant ? $merchant->mch_key : Yii::$app->params['wx_pay']['key'];
    $params['mch_appid'] = Yii::$app->params['wechatConfig']['app_id'];
    $params["mchid"] = $mch_id;
    $params['device_info'] = 'WEB';
    $params["nonce_str"] = md5(time().rand().$order_sn);
    $params['partner_trade_no'] = $order_sn;
    $params['openid'] = $openid;
    $params['check_name'] = 'NO_CHECK';
    $params['amount'] = $amount*100;
    $params['desc'] = $live_name.'直播间红包';
    $params['sign'] = self::getSign($params, $mch_key);
    $xml = self::ToXml($params);
    $url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
    $response = Curl::curl_wx_pay($url, $xml, $params['mchid']);
    $res = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)));
    return $res;
  }

  public static function getSign($param, $key) {
    //签名步骤一：按字典序排序参数
    ksort($param);
    $string = self::ToUrlParams($param);
    //签名步骤二：在string后加入KEY
    $string = $string . "&key=".$key;
    //签名步骤三：MD5加密
    $string = md5($string);
    //签名步骤四：所有字符转为大写
    $result = strtoupper($string);
    return $result;
  }

  /**
   * 格式化参数格式化成url参数
   */
  public static function ToUrlParams($param) {
    $buff = "";
    foreach ($param as $k => $v) {
      if($k != "sign" && $v != "" && !is_array($v)){
        $buff .= $k . "=" . $v . "&";
      }
    }
    $buff = trim($buff, "&");
    return $buff;
  }

  public static function ToXml($param) {
    if(!is_array($param) || count($param) <= 0) {
        throw new WxPayException("数组数据异常！");
    }
    $xml = "<xml>";
    foreach ($param as $key=>$val) {
      if (is_numeric($val)) {
        $xml.="<".$key.">".$val."</".$key.">";
      } else{
        $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
      }
    }
    $xml.="</xml>";
    return $xml;
  }

	public static function getIp() {
    $ip = "";
    /*$env = Yii::$app->params['env'];
    if ($env == 'dev') {//本地环境
      $ip = file_get_contents('https://pv.sohu.com/cityjson?ie=utf-8');
      preg_match('/{.+}/i', $ip, $m);
      $array = json_decode($m[0]);
      $ip = $array->cip;
    } else {
      if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
        $cip = $_SERVER["HTTP_CLIENT_IP"];
      } else if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
        $cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
      } else if (!empty($_SERVER["REMOTE_ADDR"])) {
        $cip = $_SERVER["REMOTE_ADDR"];
      } else {
        $cip = '';
      }
      preg_match("/[\d\.]{7,15}/", $cip, $cips);
      $ip = isset($cips[0]) ? $cips[0] : 'unknown';
      unset($cips);
    }*/

    if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
      $cip = $_SERVER["HTTP_CLIENT_IP"];
    } else if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
      $cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
    } else if (!empty($_SERVER["REMOTE_ADDR"])) {
      $cip = $_SERVER["REMOTE_ADDR"];
    } else {
      $cip = '';
    }
    preg_match("/[\d\.]{7,15}/", $cip, $cips);
    $ip = isset($cips[0]) ? $cips[0] : 'unknown';
    unset($cips);

    return $ip;
	}
}
